package io.g740.util;

import com.mysql.cj.util.StringUtils;
import io.g740.dto.FieldMappingDto;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 常量
 *
 * @author YunKaiLuo
 * @date 2024/10/22
 */
public class Constants {
    public static final String TARGET_TABLE = "target_table";

    public static String getTruncateTable(String tableName) {
        return "TRUNCATE TABLE {tableName}"
                .replace("{tableName}", StringUtils.quoteIdentifier(tableName, true))
                ;
    }

    /**
     * 获取replace into select语句
     *
     * @param sourceCatalog
     * @param sourceTableName
     * @param targetCatalog
     * @param targetTableName
     * @param fieldMappingMap
     * @return
     */
    public static String getReplaceInToTable(
            String sourceCatalog,
            String sourceTableName,
            String targetCatalog,
            String targetTableName,
            Collection<? extends FieldMappingDto> fieldMapping
    ) {

        StringBuilder result = new StringBuilder();
        result.append("REPLACE INTO ");
        result.append(StringUtils.quoteIdentifier(targetCatalog, true)
                + "." + StringUtils.quoteIdentifier(targetTableName, true)
        );
        // 目标表字段
        result.append("(");
        List<String> targetFiled = fieldMapping.stream().map(FieldMappingDto::getTargetColumnName).map(
                fieldName -> StringUtils.quoteIdentifier(fieldName, true)
        ).collect(Collectors.toList());
        result.append(String.join(",", targetFiled));
        result.append(") ");

        List<String> sourceFiled = fieldMapping.stream().map(FieldMappingDto::getSourceColumnName).collect(Collectors.toList());
        result.append(getSelectTable(sourceCatalog, sourceTableName, sourceFiled));
        return result.toString();
    }

    /**
     * 获取replace into select语句
     *
     * @param sourceCatalog
     * @param sourceTableName
     * @param targetCatalog
     * @param targetTableName
     * @param fieldMapping
     * @return
     */
    public static String getReplaceInToTableWithPlaceholders(
            String sourceCatalog,
            String sourceTableName,
            String targetCatalog,
            String targetTableName,
            Collection<? extends FieldMappingDto> fieldMapping
    ) {

        StringBuilder result = new StringBuilder();
        result.append("REPLACE INTO ");
        result.append(StringUtils.quoteIdentifier(targetCatalog, true)
                + "." + StringUtils.quoteIdentifier(targetTableName, true)
        );
        // 目标表字段
        result.append("(");
        List<String> targetFiled = fieldMapping.stream().map(FieldMappingDto::getTargetColumnName).map(
                fieldName -> StringUtils.quoteIdentifier(fieldName, true)
        ).collect(Collectors.toList());
        result.append(String.join(",", targetFiled));
        result.append(") ");

        List<String> sourceFiled = fieldMapping.stream().map((Function<FieldMappingDto, String>) fieldMappingDto -> "?").collect(Collectors.toList());
        result.append("VALUES (" + String.join(",", sourceFiled) + ");");
        return result.toString();
    }

    /**
     * 获取SELECT from 语句
     *
     * @param catalog
     * @param tableName
     * @param columnName
     * @return
     */
    public static String getSelectTable(String catalog,
                                        String tableName,
                                        Collection<String> columnName) {
        StringBuilder result = new StringBuilder();
        result.append("SELECT ");
        List<String> sourceFiled = columnName.stream().map(
                fieldName -> StringUtils.quoteIdentifier(fieldName, true)
        ).collect(Collectors.toList());
        result.append(String.join(",", sourceFiled));
        result.append(" FROM ");
        result.append(StringUtils.quoteIdentifier(catalog, true)
                + "." + StringUtils.quoteIdentifier(tableName, true)
        );
        return result.toString();
    }
}
